using System.Linq;
using System.Windows.Forms;
using CodePlex.DnD4eCampaignManager.DnD4e;
using CodePlex.DnD4eCampaignManager.Presentation.ViewInterfaces;
using CodePlex.DnD4eCampaignManager.Repositories.Interfaces;
using CodePlex.DnD4eCampaignManager.Services.Interfaces;

namespace CodePlex.DnD4eCampaignManager.Presentation
{
    public class CampaignManagerPresenter
    {
        private const string CAMPAIGN_PLANS_PREFIX = "CampaignPlans";
        private const string COMBAT_TRACKER_PREFIX = "CombatTracker";
        private const string IMPORT_MONSTER = "ImportMonster";
        private const string IMPORT_PLAYER_CHARACTER = "ImportPlayerCharacter";
        private const string LOCATION_TAB_PREFIX = "Location_";
        private const string MONSTER_TAB_PREFIX = "Monster_";
        private const string NEW_LOCATION_PREFIX = "NewLocation";
        private const string NEW_MONSTER_PREFIX = "NewMonster";
        private const string PLAYER_CHARACTER_TAB_PREFIX = "PlayerCharacter_";
        private string _clickedMenuTag;

        public CampaignManagerPresenter(ICampaignManagerView view, IPlayerCharacterRepository playerCharacterRepository,
                                        IMonsterRepository monsterRepository, ILocationRepository locationRepository,
                                        IDungeonsAndDragonsInsiderMonsterImporter dungeonsAndDragonsInsiderMonsterImporter,
                                        IDungeonsAndDragonsInsiderPlayerCharacterImporter dungeonsAndDragonsInsiderPlayerCharacterImporter)
        {
            View = view;
            PlayerCharacterRepository = playerCharacterRepository;
            MonsterRepository = monsterRepository;
            LocationRepository = locationRepository;
            DungeonsAndDragonsInsiderMonsterImporter = dungeonsAndDragonsInsiderMonsterImporter;
            DungeonsAndDragonsInsiderPlayerCharacterImporter = dungeonsAndDragonsInsiderPlayerCharacterImporter;
        }

        public ILocationRepository LocationRepository { get; set; }
        public IMonsterRepository MonsterRepository { get; set; }
        private IDungeonsAndDragonsInsiderMonsterImporter DungeonsAndDragonsInsiderMonsterImporter { get; set; }
        private IDungeonsAndDragonsInsiderPlayerCharacterImporter DungeonsAndDragonsInsiderPlayerCharacterImporter { get; set; }
        private IPlayerCharacterRepository PlayerCharacterRepository { get; set; }
        private ICampaignManagerView View { get; set; }

        public void CloseSelectedTab()
        {
            string selectedTabName = View.SelectedTabName;
            if ( !string.IsNullOrEmpty(selectedTabName) )
            {
                View.RemoveTab(selectedTabName);
                if ( selectedTabName.StartsWith(MONSTER_TAB_PREFIX) )
                {
                    DisplayMonsters();
                }
                if ( selectedTabName.StartsWith(LOCATION_TAB_PREFIX) )
                {
                    DisplayLocations();
                }
            }
            View.CloseButtonVisible = ( View.TabCount > 0 );
        }

        public void DisplayCombatTracker()
        {
            View.AddCombatTrackerTab();
        }

        public void DisplayLocations()
        {
            View.LocationNames = ( from location in LocationRepository.GetAllNames() orderby location select location ).ToArray();
        }

        public void DisplayMonsters()
        {
            View.MonsterNames = ( from monster in MonsterRepository.GetAllNames() orderby monster select monster ).ToArray();
        }

        public void DisplayPlayerCharacters()
        {
            View.PlayerCharacterNames =
                ( from playerCharacter in PlayerCharacterRepository.GetAllNames() orderby playerCharacter select playerCharacter ).ToArray();
        }

        public void ProcessMenuItemClick()
        {
            _clickedMenuTag = View.ClickedMenuItemTag;
            ProcessCombatTrackerClick();
            ProcessNewLocationClick();
            ProcessNewMonsterClick();
            ProcessImportMonsterClick();
            ProcessViewLocationClick();
            ProcessViewMonsterClick();
            ProcessViewPlayerCharacterClick();
            ProcessViewCampaignPlansClick();
            ProcessImportPlayerCharacterClick();
            SetTabCloseButtonVisibility();
        }

        private void ProcessCombatTrackerClick()
        {
            if ( _clickedMenuTag.StartsWith(COMBAT_TRACKER_PREFIX) )
            {
                View.AddCombatTrackerTab();
            }
        }

        private void ProcessImportMonsterClick()
        {
            if ( !_clickedMenuTag.StartsWith(IMPORT_MONSTER) )
            {
                return;
            }
            string monsterName = View.MonsterToImport().Trim();
            Monster monster = DungeonsAndDragonsInsiderMonsterImporter.ImportMonster(monsterName);
            if ( monster != null )
            {
                MonsterRepository.Save(monster);
                DisplayMonsters();
                View.AddMonsterEditorTab(monster.Name);
            }
            else
            {
                View.Alert(string.Format("Import failed for '{0}'", monsterName));
            }
        }

        private void ProcessImportPlayerCharacterClick()
        {
            if ( !_clickedMenuTag.StartsWith(IMPORT_PLAYER_CHARACTER) )
            {
                return;
            }
            string filePath = string.Empty;
            using ( OpenFileDialog openFileDialog = new OpenFileDialog
                                                        {
                                                            CheckFileExists = true,
                                                            RestoreDirectory = true,
                                                            Filter = "D&D Insider Character Builder File (*.dnd4e)|*.dnd4e|All files (*.*)|*.*",
                                                            FilterIndex = 1
                                                        } )
            {
                if ( openFileDialog.ShowDialog() == DialogResult.OK )
                {
                    filePath = openFileDialog.FileName;
                }
            }
            PlayerCharacter playerCharacter = DungeonsAndDragonsInsiderPlayerCharacterImporter.ImportPlayerCharacter(filePath);
            if ( playerCharacter != null )
            {
                PlayerCharacterRepository.Save(playerCharacter);
                View.AddPlayerCharacterEditorTab(playerCharacter.Name);
            }
            else
            {
                View.Alert(string.Format("Import failed for '{0}'", filePath));
            }
        }

        private void ProcessNewLocationClick()
        {
            if ( _clickedMenuTag.StartsWith(NEW_LOCATION_PREFIX) )
            {
                View.AddLocationEditorTab(string.Empty);
            }
        }

        private void ProcessNewMonsterClick()
        {
            if ( _clickedMenuTag.StartsWith(NEW_MONSTER_PREFIX) )
            {
                View.AddMonsterEditorTab(string.Empty);
            }
        }

        private void ProcessViewCampaignPlansClick()
        {
            if ( _clickedMenuTag.StartsWith(CAMPAIGN_PLANS_PREFIX) )
            {
                View.AddCampaignPlannerTab();
            }
        }

        private void ProcessViewLocationClick()
        {
            if ( _clickedMenuTag.StartsWith(LOCATION_TAB_PREFIX) )
            {
                View.AddLocationEditorTab(View.ClickedMenuItemText);
            }
        }

        private void ProcessViewMonsterClick()
        {
            if ( _clickedMenuTag.StartsWith(MONSTER_TAB_PREFIX) )
            {
                View.AddMonsterEditorTab(View.ClickedMenuItemText);
            }
        }

        private void ProcessViewPlayerCharacterClick()
        {
            if ( _clickedMenuTag.StartsWith(PLAYER_CHARACTER_TAB_PREFIX) )
            {
                View.AddPlayerCharacterEditorTab(View.ClickedMenuItemText);
            }
        }

        private void SetTabCloseButtonVisibility()
        {
            View.CloseButtonVisible = ( View.TabCount > 0 );
        }
    }
}